package serverx

import (
	"net/http"
	"reflect"

	jsoniter "github.com/json-iterator/go"

	"gitee.com/workits/pkgs/contextx"
	"gitee.com/workits/pkgs/errorx"
	"gitee.com/workits/pkgs/logx"
	"gitee.com/workits/pkgs/modelx"
	"github.com/gin-gonic/gin"
	"github.com/pkg/errors"
)

// RenderSuccess 返回成功
func RenderSuccess(c *gin.Context, data any) {
	render(c, modelx.RespWrapper{
		Msg:     "请求成功",
		Data:    data,
		Traceid: contextx.GetTraceId(c.Request.Context()),
	})
}

// RenderError 返回错误
func RenderError(c *gin.Context, err error) {
	ctx := c.Request.Context()

	// 判断错误类型
	code := 500
	msg := "未知错误，请联系管理员"
	if e, ok := errors.Cause(err).(*errorx.SysError); ok {
		code = e.Code
		msg = err.Error()
	} else {
		logx.Errorf("%+v", err, ctx)
	}

	// 向调用方返回错误
	render(c, modelx.RespWrapper{
		Code:    code,
		Msg:     msg,
		Traceid: contextx.GetTraceId(ctx),
	})
	c.Abort()
}

// 返回客户端
func render(c *gin.Context, resp modelx.RespWrapper) {
	if gin.Mode() != gin.ReleaseMode { // 非生产环境，无需加密
		c.JSON(http.StatusOK, resp)
	} else {
		// TODO
		c.JSON(http.StatusOK, resp)
	}

	// 打印返回结果
	data := resp.Data
	if data != nil {
		te := reflect.TypeOf(data).Elem()
		ve := reflect.ValueOf(data).Elem()
		for i := 0; i < te.NumField(); i++ {
			// 处理大字符串
			if te.Field(i).Tag.Get("format") == "base64" && te.Field(i).Type.Kind() == reflect.String {
				fv := ve.Field(i).Interface().(string)
				if len(fv) > 32 {
					ve.Field(i).SetString(fv[:28] + "...")
					continue
				}
			}
		}
	}
	json := jsoniter.ConfigCompatibleWithStandardLibrary
	logStr, _ := json.Marshal(resp)
	logx.Infof(string(logStr), logx.String("type", "returns"), c.Request.Context())
}
